package com.client.qiuqiu;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.client.qiuqiu.adapters.ChatAdapter;
import com.client.qiuqiu.crypto.RSA;
import com.client.qiuqiu.databinding.ActivityChatBinding;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Scanner;

public class ChatActivity extends AppCompatActivity {

    private ActivityChatBinding binding;
    private Friend receiverUser;
    private List<Chatmessage> chatmessages;
    private List<Chatmessage> receiveMessagesList;
    private ChatAdapter chatAdapter;

    Handler mainHandler,workHandler;
    HandlerThread mHandlerThread;

    boolean stopThread=false;

    String path;
    String cryptoFileAddress;
    String filename;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityChatBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        setListeners();
        loadReceiverDetails();
        init();

        // 创建与主线程关联的Handler
        mainHandler = new Handler();
        mHandlerThread = new HandlerThread("handlerThread");
        //启动线程
        mHandlerThread.start();

        //线程结束，处理消息
        workHandler = new Handler(mHandlerThread.getLooper()){
            @Override
            public void handleMessage(Message msg) {
                //主线程
                mainHandler.post(new Runnable() {
                    @Override
                    public void run () {
                        int count = chatmessages.size();

                        Collections.sort(chatmessages, (obj1, obj2) -> obj1.dateObject.compareTo(obj2.dateObject));
                        if(count==0){
                            chatAdapter.notifyDataSetChanged();
                        }else {
                            chatAdapter.notifyItemRangeInserted(count, count);
                            binding.chatRecyclerView.smoothScrollToPosition(count-1);
                        }
                        binding.chatRecyclerView.setVisibility(View.VISIBLE);
                        binding.progressBar.setVisibility(View.GONE);
                    }
                });
            }
        };

        ChatActivity.updateMessage_Thread updateMessage_thread = new ChatActivity.updateMessage_Thread();
        updateMessage_thread.start();

    }

    private void init(){
        User user = ((User)getApplicationContext());
        chatmessages = Collections.synchronizedList(new ArrayList<>());
        receiveMessagesList = new ArrayList<>();

        chatAdapter = new ChatAdapter(
                chatmessages,
                user.getId()
        );
        binding.chatRecyclerView.setAdapter(chatAdapter);

    }

    private void sendMessage(){
        User user = ((User)getApplicationContext());
        //将消息加入消息列表
        Chatmessage chatmessage = new Chatmessage();
        chatmessage.setSenderID(user.getId());
        chatmessage.setReceiverID(receiverUser.id);
        chatmessage.setMessage(binding.inputMessage.getText().toString());
        chatmessage.setDateObject(new Date());
        chatmessages.add(chatmessage);

        //发送消息线程
        ChatActivity.sendMessage_Thread sendMessage_thread = new ChatActivity.sendMessage_Thread();
        sendMessage_thread.start();
        try {
            sendMessage_thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        int count = chatmessages.size();

        Collections.sort(chatmessages, (obj1, obj2) -> obj1.dateObject.compareTo(obj2.dateObject));
        if(count==0){
            chatAdapter.notifyDataSetChanged();
        }else {
            chatAdapter.notifyItemRangeInserted(count, count);
            binding.chatRecyclerView.smoothScrollToPosition(count-1);
        }
        binding.chatRecyclerView.setVisibility(View.VISIBLE);
        binding.progressBar.setVisibility(View.GONE);
        binding.inputMessage.setText(null);
    }

    private void sendMessage(String msg){
        User user = ((User)getApplicationContext());
        //将消息加入消息列表
        Chatmessage chatmessage = new Chatmessage();
        chatmessage.setSenderID(user.getId());
        chatmessage.setReceiverID(receiverUser.id);
        chatmessage.setMessage(msg);
        chatmessage.setDateObject(new Date());
        chatmessages.add(chatmessage);

        //发送消息线程
        ChatActivity.sendMessage_Thread sendMessage_thread = new ChatActivity.sendMessage_Thread();
        sendMessage_thread.start();
        try {
            sendMessage_thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        int count = chatmessages.size();

        Collections.sort(chatmessages, (obj1, obj2) -> obj1.dateObject.compareTo(obj2.dateObject));
        if(count==0){
            chatAdapter.notifyDataSetChanged();
        }else {
            chatAdapter.notifyItemRangeInserted(count, count);
            binding.chatRecyclerView.smoothScrollToPosition(count-1);
        }
        binding.chatRecyclerView.setVisibility(View.VISIBLE);
        binding.progressBar.setVisibility(View.GONE);
        binding.inputMessage.setText(null);
    }

    class updateMessage_Thread extends Thread{
        public void run(){
            User user = ((User)getApplicationContext());
            while (!stopThread){
                List<Chatmessage> newReceiveMessage = user.getChatMessagesBox().get(receiverUser.id);
                //需更新时调用workHandler.sendMessage(message);
                //message在此只做标记作用

                if(newReceiveMessage != null){
                    if(newReceiveMessage.size() != receiveMessagesList.size()){
                        Log.e("adpter","333");
                        for (int i = receiveMessagesList.size(); i < newReceiveMessage.size(); i++){
                            receiveMessagesList.add(newReceiveMessage.get(i));
                            chatmessages.add(newReceiveMessage.get(i));
                            workHandler.sendMessage(new Message());
                        }

                    }
                }

                //间隔
                try {
                    Thread.sleep(2*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void loadReceiverDetails(){
        receiverUser = (Friend) getIntent().getSerializableExtra("friend");
        binding.textName.setText(receiverUser.name);
    }

    private void setListeners(){
        binding.imageBack.setOnClickListener(view -> onBackPressed());
        binding.layoutSend.setOnClickListener(view -> sendMessage());
        binding.imageInfo.setOnClickListener(new openFile());
    }


    @Override
    public void onBackPressed() {
        User user = ((User)getApplicationContext());
        user.getChatMessagesBox().put(receiverUser.id, chatmessages);
        stopThread = true;
        super.onBackPressed();
        Intent intent = new Intent(ChatActivity.this, Menu.class);
        startActivity(intent);
    }

    class sendMessage_Thread extends Thread{
        public void run(){
            User user = ((User)getApplicationContext());
            try {
                //获取服务器端的输出流
                PrintStream printStream = new PrintStream(user.getSocket().getOutputStream());

                //发送服务端事件
                String msg = "SendMessage";
                printStream.println(msg);

                //接收方ID
                printStream.println(receiverUser.id);
                //信息
                printStream.println(binding.inputMessage.getText().toString());

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static final int FILE_SELECTOR_CODE = 1;
    class  openFile implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("*/*");//设置类型，我这里是任意类型，任意后缀的可以这样写。
            intent.addCategory(Intent.CATEGORY_OPENABLE);
            startActivityForResult(intent, FILE_SELECTOR_CODE);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == FILE_SELECTOR_CODE && resultCode == Activity.RESULT_OK) {
            Uri uri = data.getData();
            this.path = Uri2PathUtil.getRealPathFromUri(getApplicationContext(), uri);
            Toast.makeText(this, "Send File：" + path, Toast.LENGTH_SHORT).show();

            //文件发送线程
            ChatActivity.sendFile_Thread sendFile_thread = new ChatActivity.sendFile_Thread();
            sendFile_thread.start();
        }
    }

    public String getFileNameWithSuffix(String path) {
        if(TextUtils.isEmpty(path)){
            return "";
        }
        int start = path.lastIndexOf("/");
        if (start != -1 ) {
            return path.substring(start + 1);
        } else {
            return "";
        }
    }

    //传输加密后的文件
    class sendFile_Thread extends Thread{
        public void run(){
            //加密
            //存加密文件在软件文件夹中
            User user = ((User)getApplicationContext());
            filename = getFileNameWithSuffix(path);
            String address1 = path;//输入地址
            String password = "MyPassword";//用户输入的安全码 可以是空字符串
            cryptoFileAddress = user.getCryptoFile().toString() + "/" + filename;//加密时的输出地址
            String address2 = cryptoFileAddress;

            RSA rsa = new RSA(23,47);//两个质数(请确保是质数)
            try {
                rsa.encryption(address1, address2, password);//加密
            } catch (Exception e) {
                Log.e("Error", String.valueOf(e));
            }

            File file = new File(cryptoFileAddress);

            //创建文件发送socket,一次性，每次发送文件都要建立单独连接

            //在服务端ipconfig，拿到ip填入
            SocketAddress addr = new InetSocketAddress(user.serverIP, 80);
            Socket fileSendSocket = new Socket();
            {
                try {
                    fileSendSocket.connect(addr, 1000);
                } catch (IOException e) {
                    e.printStackTrace();
                    System.exit(0);
                }
            }

            //获取服务器端的输出流
            PrintStream fileSendPrintStream = null;
            try {
                fileSendPrintStream = new PrintStream(fileSendSocket.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }

            //发送socket类型
            //客户端与服务器通讯socket
            fileSendPrintStream.println("4");
            fileSendPrintStream.println(user.getId());
            fileSendPrintStream.flush();


            //发送事件,与服务器对接流
            try {
                //获取服务器端的输出流
                PrintStream printStream = new PrintStream(user.getSocket().getOutputStream());

                //发送服务端事件
                String msg = "SendFile";
                printStream.println(msg);

                printStream.println(receiverUser.id);
                printStream.flush();

                //发送文件，文件流

                FileInputStream fileInputStream;
                DataOutputStream dataOutputStream;
                Scanner scanner = new Scanner(fileSendSocket.getInputStream());
                fileInputStream = new FileInputStream(file);
                dataOutputStream = new DataOutputStream(fileSendSocket.getOutputStream());

                if(scanner.hasNextLine()){
                    String check = scanner.nextLine();
                    System.out.println("Server check: " + check);
                }

                // 文件名和长度
                printStream.println(filename);
                printStream.flush();
                dataOutputStream.writeLong(file.length());
                dataOutputStream.flush();


                // 开始传输文件
                byte[] bytes = new byte[1024];
                int length = 0;

                if(scanner.hasNextLine()){
                    String check = scanner.nextLine();
                    System.out.println("Server check: " + check);
                }

                while((length = fileInputStream.read(bytes, 0, bytes.length)) != -1) {
                    dataOutputStream.write(bytes, 0, length);
                    dataOutputStream.flush();
                }
                Log.e("ASDFG", String.valueOf(fileInputStream.getChannel().size()));
                /*
                while((length = fileInputStream.read(bytes, 0, bytes.length)) != -1) {
                    dataOutputStream.write(bytes, 0, length);
                    if(length !=1024){
                        Log.e("ASDFG", String.valueOf(length));
                    }
                    dataOutputStream.flush();
                    n++;
                }
                //Log.e("ASDFG", String.valueOf(n));
                //Log.e("ASDFG", String.valueOf(fileInputStream.getChannel().size()));

                RSA rsa= new RSA(23,47);
                long or,med;
                int asc;
                while (true){
                    asc = fileInputStream.read();
                    if(asc == -1){
                        break;
                    }
                    or=asc;
                    med=rsa.encrypt,or);
                    //send long med
                }*/



            } catch (IOException e) {
                e.printStackTrace();
            }

            //发送消息
            Chatmessage chatmessage = new Chatmessage();
            chatmessage.setSenderID(user.getId());
            chatmessage.setReceiverID(receiverUser.id);
            chatmessage.setMessage(filename + "\n" + "Send successfully");
            chatmessage.setDateObject(new Date());
            if(user.getChatMessagesBox().get(receiverUser.id) == null){
                //之前无消息
                List<Chatmessage> chatmessages = new ArrayList<>();
                chatmessages.add(chatmessage);
                user.getChatMessagesBox().put(receiverUser.id, chatmessages);
            }else {
                //有消息
                List<Chatmessage> chatmessages = user.getChatMessagesBox().get(receiverUser.id);
                chatmessages.add(chatmessage);
                user.getChatMessagesBox().put(receiverUser.id, chatmessages);
            }
        }
    }
}